Fork me on GitHub

设计模式 - 状态

注意:所有文章除特别说明外,转载请注明出处.

简介

在该模式中,类的行为基于它的状态改变的。在该模式中创建表示各种状态的对象和一个行为随着状态对象改变而改变的context对象。允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

场景

1. 一个对象存在多个状态(不同状态下行为不同),且状态可以相互转换。

优点

1. 将不同的状态隔离

2. 将各种状态的转换逻辑分布到state的子类中,减少相互间的依赖

缺点

1. 状态多的业务场景导致类数目增加系统变复杂

相关设计模式

1. 状态模式与享元模式

状态模式

1.创建状态一个接口

public abstract class CourseVideoState {

    protected CourseVideoContext courseVideoContext;

    public void setCourseVideoContext(CourseVideoContext courseVideoContext) {
        this.courseVideoContext = courseVideoContext;
    }

    public abstract void play();
    public abstract void pause();
    public abstract void speed();
    public abstract void stop();
}

3.创建 Context 类 上下文类

public class CourseVideoContext {

    private CourseVideoState courseVideoState;

    public final static PlayState PLAY_STATE = new PlayState();
    public final static StopState STOP_STATE = new StopState();
    public final static PauseState PAUSE_STATE = new PauseState();
    public final static SpeedState SPEED_STATE = new SpeedState();

    public CourseVideoState getCourseVideoState() {
        return courseVideoState;
    }

    public void setCourseVideoState(CourseVideoState courseVideoState) {
        this.courseVideoState = courseVideoState;
        this.courseVideoState.setCourseVideoContext(this);
    }

    public void play(){
        this.courseVideoState.play();
    }

    public void speed(){
        this.courseVideoState.speed();
    }

    public void stop(){
        this.courseVideoState.stop();
    }

    public void pause(){
        this.courseVideoState.pause();
    }
}

2.创建实现接口的实体类

public class PauseState extends CourseVideoState {
    @Override
    public void play() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
    }

    @Override
    public void pause() {
        System.out.println("暂停播放视频状态");
    }

    @Override
    public void speed() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.SPEED_STATE);
    }

    @Override
    public void stop() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
    }
}


public class PlayState extends CourseVideoState {
    @Override
    public void play() {
        System.out.println("正常播放视频状态");
    }

    @Override
    public void pause() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.PAUSE_STATE);
    }

    @Override
    public void speed() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.SPEED_STATE);
    }

    @Override
    public void stop() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
    }
}

package Pattern_Design_Behavior.state;

public class SpeedState extends CourseVideoState {
    @Override
    public void play() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
    }

    @Override
    public void pause() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.PAUSE_STATE);
    }

    @Override
    public void speed() {
        System.out.println("快进状态下播放视频");
    }

    @Override
    public void stop() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
    }
}

package Pattern_Design_Behavior.state;

public class StopState extends CourseVideoState {

    @Override
    public void play() {
        super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
    }

    @Override
    public void pause() {
        System.out.println("停止状态下不能暂停 ERROR!!");
    }

    @Override
    public void speed() {
        System.out.println("停止状态下不能快进 ERROR!!");
    }

    @Override
    public void stop() {
        System.out.println("视频停止状态");
    }
}

4.使用 Context 来查看当状态 State 改变时的行为变化

package Pattern_Design_Behavior.state;

public class Test {

    public static void main(String[] args) {
        CourseVideoContext courseVideoContext = new CourseVideoContext();

        courseVideoContext.setCourseVideoState(new PlayState());
        System.out.println("当前状态是:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());

        courseVideoContext.pause();
        System.out.println("当前状态是:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());

        courseVideoContext.speed();
        System.out.println("当前状态是:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());

        courseVideoContext.stop();
        System.out.println("当前状态是:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());

        courseVideoContext.speed();
    }
}

总结

我们不关心当前context处于什么状态,context不用维护state属性。

状态模式适用于某一个对象的行为取决于该对象的状态,并且该对象的状态会在运行时转换。又或者有很多的if else判断,而这些判断只是因为状态不同而不断的切换行为。

本文标题:设计模式 - 状态

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:22:35

原始链接:http://bangjinhu.github.io/undefined/设计模式 - 状态模式 - 重要/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.